package com.atomos.strategy.action.position
{
	import flash.geom.Point;
	import flash.utils.Dictionary;
	
	import com.atomos.particle.Particle;
	import com.atomos.strategy.action.AbstractAction;
	import com.atomos.utils.MathUtils;
	import com.atomos.utils.PointUtils;
	import com.atomos.utils.RandomUtils;		

	public class EllipsisMoveAction extends AbstractAction
	{
		protected var _dData : Dictionary;
		
		protected var _nRadius1 : Number;
		protected var _nRadius2 : Number;
		protected var _nFrequency : Number;
		protected var _nRotation : Number;
		
		protected var _nRandomStart : Number;
		protected var _nRandomRadius1 : Number;
		protected var _nRandomRadius2 : Number;
		protected var _nRandomFrequency : Number;
		protected var _nRandomRotation : Number;
		
		protected var _bLockRatio : Boolean;
		
		public function EllipsisMoveAction ( radius1 : Number, radius2 : Number, frequency : Number = 1, rotation : Number = 0, randomStart : Number = 0, randomRadius1 : Number = 0, randomRadius2 : Number = 0, randomFrequency : Number = 0, randomRotation : Number = 0, lockRatio : Boolean = false )
		{
			_dData = new Dictionary ( true );
			
			_nRadius1 = radius1;
			_nRadius2 = radius2;
			_nFrequency = frequency * MathUtils.PI2;
			_nRotation  = MathUtils.deg2rad( rotation );
			
			_nRandomStart = randomStart;
			_nRandomRadius1 = randomRadius1;
			_nRandomRadius2 = randomRadius2;
			_nRandomFrequency = randomFrequency * MathUtils.PI2;
			_nRandomRotation = MathUtils.deg2rad( randomRotation );
			
			_bLockRatio = lockRatio;
		}
		
		public override function process( particle : Particle ) : void
		{
			if( !_dData [ particle ] )
			{
				var r1 : Number;
				var r2 : Number;
				if ( _bLockRatio )
				{
					var ratio : Number = _nRadius1 / _nRadius2;
					var r : Number = RandomUtils.balance( _nRandomRadius1 );
					r1 = _nRadius1 + r;
					r2 = _nRadius2 + ( r / ratio );
				}
				else
				{
					r1 = _nRadius1 + RandomUtils.balance( _nRandomRadius1 );
					r2 = _nRadius2 + RandomUtils.balance( _nRandomRadius2 );
				}
				
				_dData [ particle ] = new EllipsisData( 
											particle.position.clone(),
											RandomUtils.random( _nRandomStart ),
											r1,
											r2,
											_nFrequency + RandomUtils.balance( _nRandomFrequency ),
											_nRotation + RandomUtils.balance( _nRandomRotation ) );
			}
			
			particle.lastPosition.x = particle.position.x;			particle.lastPosition.y = particle.position.y;
			var data : EllipsisData = _dData[ particle ] as EllipsisData;
			
			var pos : Point = data.position;
			var a : Number = data.angle;
			var p : Point = new Point ( data.radius1 * Math.sin( a ), 
										data.radius2 * Math.cos( a ) );
			
			pos.x += particle.velocity.x * _nTimeStep;
			pos.y += particle.velocity.y * _nTimeStep;
			
			PointUtils.rotate( p, data.rotation );
			
			particle.position.x = pos.x + p.x;
			particle.position.y = pos.y + p.y;
			
			data.angle += data.frequency * _nTimeStep; 
		}

	}
}

import flash.geom.Point;

internal class EllipsisData
{
	public var position : Point;
	public var angle : Number;
	
	public var radius1 : Number;
	public var radius2 : Number;
	public var frequency : Number;
	public var rotation : Number;
	
	public function EllipsisData ( position : Point, angle : Number = 0, radius1 : Number = 1, radius2 : Number = 1, frequency : Number = 1, rotation : Number = 0 )
	{
		this.position = position;
		this.angle = angle;
		
		this.frequency = frequency;
		this.radius1 = radius1;
		this.radius2 = radius2;
		this.rotation = rotation;
	}
}